/**
 * @class   wosh::MessageNetworkForwarding
 * @brief   This class holds information about previous forwarders nodes (hosts)
 *
 * @see     wosh::Message
 * @see     wosh::NetworkManager
 ****************************************************************************
 * @version $Id: MessageNetworkForwarding.h 2863 2010-08-07 04:28:58Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_MessageNetworkForwarding_H__
 #define __WOSH_Core_MessageNetworkForwarding_H__

 #include <woshDefs.h>
 #include <core/Serialization.h>
 #include <string>
 #include <vector>
 #include <core/Utilities.h>


namespace wosh {

struct MessageNetworkForwarder {
	std::string name;
	long timestamp;
};

class MessageNetworkForwarding : public virtual ISerializable
 {
	WOSH_SERIALIZABLE(wosh::MessageNetworkForwarding)
	WOSH_COMPARE_RTTI(wosh::MessageNetworkForwarding)

	public:

		MessageNetworkForwarding() { }

		MessageNetworkForwarding( const std::string& hostname ) {
			addHost(hostname);
		 }

		MessageNetworkForwarding( const MessageNetworkForwarding& m ) {
			*this = m;
		 }

		virtual ~MessageNetworkForwarding() { }



/** @name Getters
 * @{
 ******************************************************************************/
	public:

		int getHostCount() const							{ return this->hosts.size(); }

		std::vector<MessageNetworkForwarder>& getHosts()		{ return this->hosts; }
		const std::vector<MessageNetworkForwarder>& getHosts() const
															{ return this->hosts; }
		int getHostIndex( const std::string& hostname ) const
		 {
			int index = -1;
			std::vector<MessageNetworkForwarder>::const_iterator it;
			for ( it=this->hosts.begin(); it!=this->hosts.end(); ++it, ++index ) {
				if ( (*it).name != hostname ) continue;
				return index;
			 }
			return -1;
		 }

		long getLastTimestamp() const {
			if ( this->hosts.empty() ) return 0;
			return this->hosts.back().timestamp;
		 }

//@}
/** @name Setters
 * @{
 ******************************************************************************/
	public:

		void addHost( const std::string& hostname ) {
			MessageNetworkForwarder mnf;
			mnf.name = hostname;
			mnf.timestamp = Utilities::std_time();
			this->hosts.push_back(mnf);
		 }

//@}
/** @name Operators Overloading
 * @{
 ******************************************************************************/
	public:

		virtual MessageNetworkForwarding& operator=(const MessageNetworkForwarding& m)
		{
			if (this == &m) return *this; // same object?

			this->hosts.clear();
			std::vector<MessageNetworkForwarder>::const_iterator it;
			for ( it=m.hosts.begin(); it!=m.hosts.end(); ++it ) {
				MessageNetworkForwarder mnf;
				mnf.name = (*it).name;
				mnf.timestamp = (*it).timestamp;
				this->hosts.push_back(mnf);
			 }

			return *this;
		 }

		virtual bool operator==(const MessageNetworkForwarding &other) const
		 {
			return ( this->hosts.size() == other.hosts.size() );
		 }

		virtual bool operator!=(const MessageNetworkForwarding &other) const
															{ return !(*this == other);  }

//@}
/** @name Serialization interface
 * @{
 ******************************************************************************/
	public:
		virtual std::string toString() const				{ return ""; }
		virtual bool updateHash( DataHashContext* hash_context ) const {
			if ( hash_context == NULL ) return false;
			bool ret = true;
			std::vector<MessageNetworkForwarder>::const_iterator it;
			for ( it=this->hosts.begin(); it!=this->hosts.end(); ++it )
				ret = hash_context->update( (*it).name ) & ret;
				ret = hash_context->update( (*it).timestamp ) & ret;
			return ret;
		 }

//@}
	protected:
		std::vector<MessageNetworkForwarder> hosts;	///< hostname => local-epoch


}; // class def

}; // namespace wosh

#endif //__WOSH_Core_MessageNetworkForwarding_H__
